package com.example.mytext;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.ref.WeakReference;

public class VideoTakeButton extends View {

    private static final String TAG = "VideoTakeButton";

    /**
     * 外边框半透明圆的画笔
     */
    private Paint mPaint0;

    /**
     * 内部圆的画笔
     */
    private Paint mPaint1;

    /**
     * 进度条的画笔
     */
    private Paint mPaint2;

    /**
     * 进度条动画
     */
    private ValueAnimator mProgressAni;

    /**
     * 最大拍摄时间，视频只能拍这么久
     */
    private int mMaxTime = 15;

    /**
     * 视频的最小拍摄时间，小于这个时间都按拍照处理
     */
    private float mMinTime = 0.6F;

    /**
     * 外边框的半透明圆的尺寸
     */
    private float bigCircleRadius = 0;
    /**
     * 外边框半透明圆的动画开始尺寸
     */
    private float bigCircleStartRadius = 0;
    /**
     * 外边框半透明圆的动画结束尺寸
     */
    private float bigCircleEndRadius = 0;

    /**
     * 内部圆的尺寸
     */
    private float smallCircleRadius = 0;
    /**
     * 内部圆的动画开始尺寸
     */
    private float smallCircleStartRadius = 0;
    /**
     * 内部圆的动画结束尺寸
     */
    private float smallCircleEndRadius = 40;

    /**
     * 拍摄视频的进度条
     */
    private float progress = 0;

    /**
     * 开始点击的消息码
     */
    private static final int START_CLICK = 0x001;
    /**
     * 长按事件的消息码
     */
    private static final int LONG_CLICK = 0x002;

    /**
     * 按钮按下时间
     */
    private long mStartTime = 0L;

    /**
     * 按钮抬起时间
     */
    private long mEndTime = 0L;
    /**
     * 长按最短时间  单位毫秒
     */
    public long LONG_CLICK_MIN_TIME = 800L;


    public VideoTakeButton(Context context) {
        super(context);
        init(context);
    }

    public VideoTakeButton(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public VideoTakeButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        mPaint0 = new Paint();
        mPaint0.setColor(Color.WHITE);
        mPaint0.setAlpha(150);

        mPaint1 = new Paint();
        mPaint1.setColor(Color.WHITE);
        mPaint1.setAlpha(255);

        mPaint2 = new Paint();
        mPaint2.setColor(Color.GREEN);
        mPaint2.setAlpha(255);

        //进度条的属性动画
        mProgressAni = ValueAnimator.ofFloat(0, 360f);
        mProgressAni.setDuration(mMaxTime * 1000);
    }

    private ViewHandler viewHandler = new ViewHandler(this);

    static class ViewHandler extends android.os.Handler {

        private WeakReference<VideoTakeButton> weakReference = null;

        public ViewHandler(VideoTakeButton videoTakeButton) {
            weakReference = new WeakReference<>(videoTakeButton);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (weakReference == null || weakReference.get() == null) return;
            final VideoTakeButton videoTakeButton = weakReference.get();
            switch (msg.what) {
                case VideoTakeButton.START_CLICK:
                    videoTakeButton.startAnimationClick();
                    break;
                case VideoTakeButton.LONG_CLICK:
                    if (videoTakeButton.callBack != null) {
                        videoTakeButton.callBack.takeVideoStart();
                    }
                    break;
            }
        }
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        float x = getWidth();
        float y = getHeight();

        float pointX = x / 2;
        float pointY = y / 2;

        bigCircleStartRadius = x / 2 - x / 15;
        bigCircleEndRadius = x / 2;

        smallCircleStartRadius = x * 2 / 5 - x / 15;
        smallCircleEndRadius = (x * 2 / 5 - x / 15) / 2;
        if (isRecording) {
            canvas.drawCircle(pointX, pointY, bigCircleRadius, mPaint0);
            canvas.drawCircle(pointX, pointY, smallCircleRadius, mPaint1);
            //使用离屏绘制
            int layerID = canvas.saveLayer(0, 0, getWidth(), getHeight(), mPaint2, Canvas.ALL_SAVE_FLAG);
            canvas.drawArc(x / 15, x / 15, x - x / 15, x - x / 15, 270, progress, true, mPaint2);
            mPaint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
            canvas.drawArc(0, 0, x, x, 270, progress, true, mPaint2);
            mPaint2.setXfermode(null);
            canvas.restoreToCount(layerID);
        } else {
            bigCircleRadius = bigCircleStartRadius;
            canvas.drawCircle(pointX, pointY, bigCircleRadius, mPaint0);

            smallCircleRadius = smallCircleStartRadius;
            canvas.drawCircle(pointX, pointY, smallCircleRadius, mPaint1);
        }

    }

    private void startAnimationClick() {
        ValueAnimator smallCircle = ValueAnimator.ofFloat(smallCircleStartRadius, smallCircleEndRadius);
        smallCircle.setDuration(300);
        smallCircle.addUpdateListener(animation -> {
            smallCircleRadius = (float) animation.getAnimatedValue();
            invalidate();
        });
        ValueAnimator bigCircle = ValueAnimator.ofFloat(bigCircleStartRadius, bigCircleEndRadius);
        bigCircle.setDuration(300);
        bigCircle.addUpdateListener(animation -> {
            if (isRecording) {
                bigCircleRadius = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        smallCircle.start();
        bigCircle.start();
        smallCircle.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }

            @Override
            public void onAnimationEnd(Animator animator) {
                //开始绘制圆形进度条
                if (isRecording) {
                    startAniProgress();
                }
            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });
    }

    private void startAniProgress() {
        if (mProgressAni == null) return;
        mProgressAni.start();
        mProgressAni.addUpdateListener(valueAnimator -> {
            progress = (float) valueAnimator.getAnimatedValue();
            postInvalidate();
        });
        mProgressAni.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                isRecording = false;
                progress = 0;
                postInvalidate();
            }
        });
    }

    private boolean isRecording = false;

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isRecording = true;
                mStartTime = System.currentTimeMillis();
                viewHandler.sendEmptyMessage(START_CLICK);
                viewHandler.sendEmptyMessageDelayed(LONG_CLICK, LONG_CLICK_MIN_TIME);
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                isRecording = false;
                mEndTime = System.currentTimeMillis();
                if (mEndTime - mStartTime < LONG_CLICK_MIN_TIME) {
                    if (viewHandler.hasMessages(LONG_CLICK)) {
                        viewHandler.removeMessages(LONG_CLICK);
                    }
                    if (callBack != null) {
                        callBack.takePhoto();
                    }
                } else {
                    if (mProgressAni != null && progress / 10 < mMinTime) {
                        if (callBack != null) {
                            callBack.takePhoto();
                        }
                    } else {
                        if (callBack != null) {
                            callBack.takeVideoEnd();
                        }
                    }
                }
                if (mProgressAni != null) {
                    mProgressAni.cancel();
                }
                break;
        }
        return true;
    }

    interface CallBack {

        void takePhoto();

        void takeVideoStart();

        void takeVideoEnd();

    }

    private CallBack callBack;

    public void setCallBack(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int screenWidth = getScreenWidth();
        int width = screenWidth * 23 / 100;
        setMeasuredDimension(width, width);
    }

    /**
     * 获取屏幕宽度
     *
     * @return
     */
    private int getScreenWidth() {
        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.widthPixels;
    }

}